package org.jsola.hr.service.impl;

import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.jsola.cache.ICache;
import org.jsola.common.StrKit;
import org.jsola.exception.ParamException;
import org.jsola.hr.common.CacheKeyKit;
import org.jsola.hr.common.wechat.QRCodeUtils;
import org.jsola.hr.service.IQRCodeService;
import org.jsola.hr.vo.DynamicCodeVO;
import org.jsola.hr.vo.QRCodeVO;
import org.jsola.user.core.TokenUser;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.Date;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Objects;

@Slf4j
@Service("hrIQRCodeServiceImpl")
public class IQRCodeServiceImpl implements IQRCodeService {

    @Autowired
    private ICache cache;

    @Autowired
    private QRCodeUtils qrCodeUtils;

    @Override
    public QRCodeVO getQRCode(String companyId, TokenUser tokenUser) {

        String key = CacheKeyKit.getQRCode(companyId);
        return cache.get(key);
    }

    @Override
    public QRCodeVO generateQRCode(String companyId, Integer postType, Integer validDays, String flowId, Date expireDate,
                                   Integer status, TokenUser tokenUser) {
        ParamException.notNull(expireDate, "过期时间不能为空");
        if (expireDate.before(new Date())) {
            throw new ParamException("过期时间不能早于当前时间");
        }
        String siteId = tokenUser.getSiteId();
        String key = CacheKeyKit.getQRCode(companyId);
        String params = "params=" + key;
        // 二维码地址
        String qrCodeUrl = qrCodeUtils.getQRCode(params, siteId);
        QRCodeVO qrCodeVO = new QRCodeVO();
        qrCodeVO.setCompanyId(companyId);
        qrCodeVO.setPostType(postType);
        qrCodeVO.setValidDays(validDays);
        qrCodeVO.setQrCodeUrl(qrCodeUrl);
        qrCodeVO.setFlowId(flowId);
        qrCodeVO.setStatus(status);
        qrCodeVO.setExpireDate(expireDate);
        qrCodeVO.setRedisKey(key);
        qrCodeVO.setSiteId(siteId);
        qrCodeVO.setOperationUserId(tokenUser.getUserId());
        cache.set(key, qrCodeVO);
        return qrCodeVO;
    }

    @Override
    public QRCodeVO generateQRCode(QRCodeVO qrCodeVO, TokenUser tokenUser) {
        if (Objects.nonNull(qrCodeVO.getExpireDate())) {
            if (qrCodeVO.getExpireDate().before(new Date())) {
                throw new ParamException("过期时间不能早于当前时间");
            }
        }
        String siteId = tokenUser.getSiteId();
        String paramsKey = CacheKeyKit.getQRCode(qrCodeVO.getCompanyId());
        String generateKey = CacheKeyKit.getQRCodeAndUserId(qrCodeVO.getCompanyId(), tokenUser.getUserId());
        String params = "params=" + generateKey;
        // 二维码地址
        String qrCodeUrl = qrCodeUtils.getQRCode(params, siteId);
        qrCodeVO.setQrCodeUrl(qrCodeUrl);
        qrCodeVO.setRedisKey(generateKey);
        qrCodeVO.setSiteId(siteId);
        qrCodeVO.setOperationUserId(tokenUser.getUserId());
        cache.set(generateKey, qrCodeVO);
        return qrCodeVO;
    }

    @Override
    public QRCodeVO getByKey(String key) {
        return cache.get(key);
    }

    @Override
    public QRCodeVO getManageQRCode(String companyId, String channelId, Integer type, TokenUser tokenUser) {
        String siteId = tokenUser.getSiteId();
        String userId = tokenUser.getUserId();
        String key = CacheKeyKit.getManageQRCode(companyId, type, userId);

        String params = "params=" + key;
        // 二维码地址
        String qrCodeUrl = qrCodeUtils.getManageQRCode(params, siteId);
        QRCodeVO qrCodeVO1 = new QRCodeVO();
        qrCodeVO1.setCompanyId(companyId);
        qrCodeVO1.setQrCodeUrl(qrCodeUrl);
        qrCodeVO1.setRedisKey(key);
        qrCodeVO1.setType(type);
        qrCodeVO1.setSiteId(siteId);
        qrCodeVO1.setUserId(userId);
        qrCodeVO1.setOperationUserId(userId);
        if (StrKit.isNotEmpty(companyId)) {
            qrCodeVO1.setChannelId(channelId);
        }
        long ttl = 3 * 24 * 60 * 60 * 1000;
        cache.set(key, qrCodeVO1, ttl);
        return qrCodeVO1;
    }

    @Override
    public DynamicCodeVO getDynamicCode(String companyId, String channelId, String oldCode, Integer type, TokenUser tokenUser) {
        // 删除之前的动态码
        if (StrKit.isNotEmpty(oldCode)) {
            cache.delKey(CacheKeyKit.getDynamicCode(oldCode));
        }
        String siteId = tokenUser.getSiteId();
        String userId = tokenUser.getUserId();
        String code = generateFourNumber();
        String key = CacheKeyKit.getDynamicCode(code);
        DynamicCodeVO dynamicCodeVO = cache.get(code);
        // 如果是已存在的key,重新生成key,避免动态码重复
        while (Objects.nonNull(dynamicCodeVO)) {
            code = generateFourNumber();
            key = CacheKeyKit.getDynamicCode(code);
            dynamicCodeVO = cache.get(code);
        }
        // 每次请求接口都会生成新的动态码,之前的就会失效
        DynamicCodeVO codeVO = new DynamicCodeVO();
        codeVO.setCode(code);
        codeVO.setSiteId(siteId);
        codeVO.setUserId(userId);
        codeVO.setOperationUserId(userId);
        codeVO.setCompanyId(companyId);
        if (StrKit.isNotEmpty(companyId)) {
            codeVO.setChannelId(channelId);
        }
        codeVO.setCreateDate(new Date());
        codeVO.setType(type);
        // 有效期30分钟,单位ms
        long expire = 30 * 60 * 1000L;
        codeVO.setExpire(expire);
        // 有效时间30分钟
        cache.set(key, codeVO, expire);
        log.info("生成动态码：{}", code);
        return codeVO;
    }

    @Override
    public DynamicCodeVO getByDynamicCode(String code) {
        String key = CacheKeyKit.getDynamicCode(code);
        DynamicCodeVO codeVO = cache.get(key);
        if (codeVO == null) {
            log.info("动态码:{}不存在或已失效,请联系管理员", code);
        }
        ParamException.notNull(codeVO, "动态码不存在或已失效,请联系管理员");
        return codeVO;
    }

    @Override
    public String generateSalaryQRCode(String batchId, Integer batchType, String siteId, TokenUser tokenUser) {

        LinkedHashMap<String, Object> linkedHashMap = new LinkedHashMap<>();
        linkedHashMap.put("batchId", batchId);
        linkedHashMap.put("batchType", batchType);
        linkedHashMap.put("siteId", siteId);
        String params = getParams(linkedHashMap);
        // 二维码地址
        return qrCodeUtils.getSalaryQRCode(params, tokenUser.getSiteId());
    }

    @Override
    public QRCodeVO getQRCodeByCompanyId(String companyId, TokenUser tokenUser) {
        String key = CacheKeyKit.getQRCodeAndUserId(companyId, tokenUser.getUserId());
        return cache.get(key);
    }

    /**
     * 拼接get请求的参数
     */
    private String getParams(LinkedHashMap<String, Object> linkedHashMap) {
        StringBuilder params = new StringBuilder();
        for (Map.Entry<String, Object> entry : linkedHashMap.entrySet()) {
            if (StrKit.isNotEmpty(entry.getValue())) {
                params.append(entry.getKey())
                        .append("=")
                        .append(entry.getValue())
                        .append("&");
            }
        }

        String str = params.toString();
        if (StrKit.isNotEmpty(str)) {
            return str.substring(0, str.length() - 1);
        } else {
            return StringUtils.EMPTY;
        }

    }


    /**
     * 生成四位动态码
     */
    private String generateFourNumber() {
        return String.valueOf((int) Math.round(Math.random() * (9999 - 1000) + 1000));
    }
}
